package services

import (
	comm "com.wangzhumo.lottery/common"
	"com.wangzhumo.lottery/dao"
	"com.wangzhumo.lottery/datasource"
	"com.wangzhumo.lottery/models"
	"fmt"
	"github.com/gomodule/redigo/redis"
	"log"
)

type UserService interface {
	Get(uid int) (*models.UserBlack, error)
	GetAll(page int, size int) ([]models.UserBlack, error)
	CountAll() int64
	Update(user *models.UserBlack, columns []string) error
	Insert(user *models.UserBlack) error
}

type blackUserService struct {
	dao *dao.BlackUserDao
}


// 这里的Cache
// 使用hash redis来处理，频繁读取，并且会经常读取、更新某个用户
// -------------------cache---------------------

func (b *blackUserService) getByCache(uid int) *models.UserBlack {
	key:= fmt.Sprintf("info_user_%d",uid)
	redisConn := datasource.InstanceRedis()
	stringMap, err := redis.StringMap(redisConn.Do("HGETALL", key))
	if err != nil {
		log.Println("UserService.getByCache redis HGETALL key = ",key," err + ",err)
		return nil
	}
	userid := comm.GetInt64FromStringMap(stringMap,"Id",0)
	if userid <= 0 {
		return nil
	}

	userInfo := &models.UserBlack{
		Id: int(userid),
		Username:   comm.GetStringFromStringMap(stringMap,"Username",""),
		Blacktime:  int(comm.GetInt64FromStringMap(stringMap,"Blacktime",0)),
		Realname:   comm.GetStringFromStringMap(stringMap,"Realname",""),
		Mobile:     comm.GetStringFromStringMap(stringMap,"Mobile",""),
		Address:    comm.GetStringFromStringMap(stringMap,"Address",""),
		SysUpdated: int(comm.GetInt64FromStringMap(stringMap,"SysUpdated",0)),
		SysCreated: int(comm.GetInt64FromStringMap(stringMap,"SysCreated",0)),
		SysIp:     comm.GetStringFromStringMap(stringMap,"SysIp",""),
	}

	return userInfo
}

func (b *blackUserService) saveToCache(user *models.UserBlack){
	if user == nil || user.Id <= 0 {
		return
	}
	key := fmt.Sprintf("info_user_%d",user.Id)
	redisConn := datasource.InstanceRedis()
	params := redis.Args{key}
	// 添加值参数
	params = params.Add(user.Id)
	if user.Username != "" {
		params = params.Add(params,"Username",user.Username)
		params = params.Add(params,"Blacktime",user.Blacktime)
		params = params.Add(params,"Realname",user.Realname)
		params = params.Add(params,"Mobile",user.Mobile)
		params = params.Add(params,"Address",user.Address)
		params = params.Add(params,"SysUpdated",user.SysUpdated)
		params = params.Add(params,"SysCreated",user.SysCreated)
		params = params.Add(params,"SysIp",user.SysIp)
	}

	_, err := redisConn.Do("HMSET", params)
	if err != nil {
		log.Println("UserService.saveToCache redis HMSET key = ",key," err + ",err)
	}

}

func (b *blackUserService) updateCache(user *models.UserBlack, columns []string)  {
	if user == nil || user.Id <= 0 {
		return
	}
	key := fmt.Sprintf("info_user_%d",user.Id)
	redisConn := datasource.InstanceRedis()
	_, err := redisConn.Do("DEL", key)
	if err != nil {
		log.Println("UserService.updateCache redis DEL key = ",key," err + ",err)
	}
}

// -------------------cache---------------------



// Get 获取用户
func (b *blackUserService) Get(uid int) (*models.UserBlack, error) {
	user := b.getByCache(uid)
	if user == nil || user.Id <= 0 {
		user, _ := b.dao.Get(uid)
		if user == nil || user.Id <= 0 {
			// 如果为空，也存入一个空的到redis,避免下次还要读数据库
			user = &models.UserBlack{Id: uid}
		}
		b.saveToCache(user)
	}

	return user,nil
}

func (b *blackUserService) GetAll(page int, size int) ([]models.UserBlack, error) {
	return b.dao.GetAll(page, size)
}

func (b *blackUserService) CountAll() int64 {
	return b.dao.CountAll()
}

func (b *blackUserService) Update(user *models.UserBlack, columns []string) error {
	b.updateCache(user,columns)
	return b.dao.Update(user, columns)
}

func (b *blackUserService) Insert(user *models.UserBlack) error {
	return b.dao.Insert(user)
}

func NewBlackUserService() UserService {
	return &blackUserService{dao: dao.NewBlackUserDao(datasource.InstanceDB())}
}
